/**
 * 深拷贝
 */

// let k = JSON.parse(JSON.stringify(obj)); //这样可以深拷贝 但是无法拷贝函数正则

let obj1 = {
    name: 'obj.name',
    un: undefined,
    nu: null,
    arr: [1, 2, 3, [4, 5]],
    sy: Symbol(123),
    say: function() {
        console.log(this.name);
    },
    reg: /\d{6}/g,
    date: new Date(),
    child: {
        name: 'child.name'
    }
}
const obj2 = deepCopy(obj1)
obj2.child.city = 'shanghai'
console.log(obj1.child.name)
console.log(obj1);
console.log(obj2);


// 没有考虑 正则
// function 和 date

function deepCopy(obj) {
    if (typeof obj !== 'object' || obj == null) {
        return obj;
    }
    let result;
    if (obj instanceof Array) {
        result = [];
    } else {
        result = {};
    }
    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            result[key] = deepCopy(obj[key]);
        }
    }
    return result
}

// function isObject(obj) {
//     return Object.prototype.toString.call(obj) === '[object Object]' //若是正则会返回'[object RegExp]'
// }

// function deepCopy(obj) {
//     if (!isObject(obj)) return obj
//     let result;
//     result = obj instanceof Array ? [] : {};
//     for (let key in obj) {
//         if (obj.hasOwnProperty(key)) {
//             result[key] = deepCopy(obj[key]);
//         }
//     }
//     return result
// }

//复杂版考虑正则 function 和 date
// function isObject(obj) {
//     return Object.prototype.toString.call(obj) === '[object Object]'
// }

// function deepCopy(source, hash = new Map()) {
//     // 判断如果参数不是一个对象，返回改参数
//     if (!isObject(source)) return source;
//     if (hash.has(source)) return hash.get(source); // 如果拷贝过该对象，则直接返回该对象
//     // 判断参数是对象还是数组来初始化返回值
//     let res = Array.isArray(source) ? [] : {};
//     hash.set(source, res); // 哈希表添加新对象
//     // 循环参数对象的key
//     for (let key in source) {
//         // 如果该key属于参数对象本身
//         if (Object.prototype.hasOwnProperty.call(source, key)) {
//             // 如果该key的value值是对象，递归调用深拷贝方法进行拷贝
//             if (isObject(source[key])) {
//                 res[key] = deepCopy(source[key], hash);
//             } else {
//                 // 如果该key的value值不是对象，则把参数对象key的value值赋给返回值的key
//                 res[key] = source[key];
//             }
//         }
//     }
//     // 返回返回值
//     return res;
// };